﻿using Architecture.Domain.Dto;
using Architecture.Domain.Dto.MenuDto;
using Architecture.Repository;
using Architecture.Repository.Interface;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO.Pipelines;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;

namespace Architecture.Domain.Service.MenuServices
{
    /// <summary>
    /// 菜单服务
    /// </summary>
    public class MenuService : IMenuService
    {
        /// <summary>
        /// 用户信息仓储
        /// </summary>
        protected readonly IUserInfoRepository _userInfoRepository;

        /// <summary>
        ///  用户信息角色服务
        /// </summary>
        protected readonly IUserInfoRoleRepository _userInfoRoleRepository;

        /// <summary>
        /// 角色仓储
        /// </summary>
        protected readonly IRoleRepository _roleRepository;

        /// <summary>
        /// 菜单仓储
        /// </summary>
        protected readonly IMenuRepository _menuRepository;

        /// <summary>
        /// 菜单角色仓储
        /// </summary>
        private readonly IMenuRoleRepository _menuRoleRepository;


        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="userInfoRepository">用户信息仓储</param>
        /// <param name="userInfoRoleRepository">用户信息角色服务</param>
        /// <param name="roleRepository">角色仓储</param>
        /// <param name="menuRepository">菜单仓储</param>
        /// <param name="menuRoleRepository">菜单角色仓储</param>
        public MenuService(IUserInfoRepository userInfoRepository, IUserInfoRoleRepository userInfoRoleRepository, IRoleRepository roleRepository, IMenuRepository menuRepository, IMenuRoleRepository menuRoleRepository)
        {
            _userInfoRepository = userInfoRepository;
            _userInfoRoleRepository = userInfoRoleRepository;
            _roleRepository = roleRepository;
            _menuRepository = menuRepository;
            _menuRoleRepository = menuRoleRepository;
        }

        /// <summary>
        /// 添加菜单
        /// </summary>
        /// <param name="menu">菜单信息</param>
        /// <returns>返回受影响的行数</returns>
        public async Task<int> AddMenu(Menu menu)
        {
            var result = await _menuRepository.GetAsync(x => x.MenuName == menu.MenuName);
            if (result.Count > 0)
            {
                return -2;
            }
            menu.Sort = 0;
            menu.CreatedDate = DateTime.Now;
            return await _menuRepository.AddAsync(menu);
        }

        /// <summary>
        /// 获取菜单列表
        /// </summary>
        /// <returns>返回菜单列表</returns>
        public async Task<PagingMenuDto<MenuListDto>> GetMenus(int userId, int PageIndex, int PageSize, string? MenuName)
        {
            var paging = new PagingMenuDto<MenuListDto>();
            var list = (from a in await _userInfoRepository.GetAllAsync()
                        join b in await _userInfoRoleRepository.GetAllAsync()
                        on a.UserId equals b.UserId
                        join c in await _roleRepository.GetAllAsync()
                        on b.RoleId equals c.RoleId
                        join d in await _menuRoleRepository.GetAllAsync()
                        on c.RoleId equals d.RID
                        join e in await _menuRepository.GetAllAsync()
                        on d.MID equals e.MenuId
                        where a.UserId == userId && !a.IsDeleted && !b.IsDeleted && !c.IsDeleted && !e.IsDeleted
                        select new MenuListDto
                        {
                            MenuId = e.MenuId,
                            MenuName = e.MenuName,
                            Url = e.Url,
                            PID = e.PID,
                            Sort = e.Sort,
                            CreatedBy = e.CreatedBy,
                            CreatedDate = e.CreatedDate,
                            UpdatedBy = e.UpdatedBy,
                            UpdatedDate = e.UpdatedDate,
                            DeletedBy = e.DeletedBy,
                            DeletedDate = e.DeletedDate,
                            IsDeleted = e.IsDeleted,
                        }).ToList();

            if (!string.IsNullOrEmpty(MenuName))
            {
                list = list.Where(x => x.MenuName.Contains(MenuName)).ToList();
            }

            paging.totalCount = list.Count();
            paging.pageCount = (int)Math.Ceiling(list.Count() * 1.0 / PageSize);
            paging.list = list.OrderByDescending(x => x.CreatedDate).Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList();
            return paging;

            //var menulist = await _menuRepository.GetAllAsync();
            //var list = from a in await _menuRepository.GetAllAsync()
            //           where !a.IsDeleted
            //           select new 
            //           { 
            //               a.MenuId,
            //               a.MenuName,
            //               a.Url,
            //               a.PID,
            //               a.Sort,
            //               a.CreatedBy,
            //               a.CreatedDate,
            //               a.UpdatedBy,
            //               a.UpdatedDate,
            //               a.DeletedBy,
            //               a.DeletedDate,
            //               a.IsDeleted,
            //               MenuNames= menulist.FirstOrDefault(x => x.MenuId == a.PID)
            //           };
            //return list.ToList();
        }

        /// <summary>
        /// 反填菜单模型
        /// </summary>
        /// <param name="menuId">菜单ID</param>
        /// <returns>返回菜单模型</returns>
        public async Task<Menu> GetMenuModel(int menuId)
        {
            return await _menuRepository.GetModelAsync(menuId);
        }

        /// <summary>
        /// 修改菜单信息
        /// </summary>
        /// <param name="menu">菜单模型</param>
        /// <returns>返回受影响的行数</returns>
        public async Task<int> UpdateMenu(Menu menu)
        {
            var result = await _menuRepository.GetAsync(x => x.MenuName == menu.MenuName);
            if (result.Count > 0)
            {
                return -2;
            }
            menu.UpdatedBy = "";
            menu.UpdatedDate = DateTime.Now;
            return await _menuRepository.UpdateAsync(menu);
        }

        /// <summary>
        /// 获取菜单列表
        /// </summary>
        /// <param name="menuName">菜单名称</param>
        /// <returns>返回菜单列表</returns>
        public async Task<List<Menu>> GetMenuList(string menuName)
        {
            return await _menuRepository.GetAsync(x => x.MenuName == menuName);
        }

        /// <summary>
        /// 获取菜单的子集数量
        /// </summary>
        /// <param name="menuId">菜单ID</param>
        /// <returns>返回菜单的子集数量</returns>
        public async Task<int> GetMenuCount(int menuId)
        {
            var res = await _menuRepository.GetAsync(x => x.PID == menuId);
            return res.Count();
        }

        /// <summary>
        /// 删除菜单
        /// </summary>
        /// <param name="menuId">菜单ID</param>
        /// <returns>返回受影响的行数</returns>
        public async Task<int> DeleteMenu(int menuId)
        {
            var res = await _menuRepository.GetModelAsync(menuId);
            if (res != null && res.IsDeleted == false)
            {
                res.IsDeleted = true;
                res.DeletedBy = "";
                res.DeletedDate = DateTime.Now;
                await DeleteMenuChildren(res);
                return await _menuRepository.UpdateAsync(res);
            }
            return 0;
        }

        /// <summary>
        /// 递归 删除菜单及所有子集及所有子集的子集
        /// </summary>
        /// <param name="menu">菜单实体</param>
        /// <returns>返回受影响的行数</returns>
        public async Task DeleteMenuChildren(Menu menu)
        {
            menu.IsDeleted = true;
            menu.DeletedBy = "";
            menu.DeletedDate = DateTime.Now;
            var res = await _menuRepository.GetAsync(x => x.PID == menu.MenuId);
            foreach (var item in res)
            {
                await DeleteMenuChildren(item);
            }
        }

        /// <summary>
        /// 菜单部分信息
        /// </summary>
        /// <returns>返回菜单部分信息</returns>
        public async Task<List<MenuRecursionDto>> GetMenuInfo(int pid = 0)
        {

            var list = (from a in await _menuRepository.GetAllAsync()
                        where a.PID == pid && !a.IsDeleted
                        select new MenuRecursionDto
                        {
                            id = a.MenuId,
                            label = a.MenuName,
                            children = GetMenuInfo(a.MenuId).Result
                        });
            return list.Distinct().ToList();
        }

        /// <summary>
        /// 显示菜单（没有用递归）
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns>返回菜单信息</returns>
        public async Task<List<MenuDto>> GetMenu(int userId)
        {
            var res = from u in await _userInfoRepository.GetAllAsync()
                      join ur in await _userInfoRoleRepository.GetAllAsync() on u.UserId equals ur.UserId
                      join rm in await _menuRoleRepository.GetAllAsync() on ur.RoleId equals rm.RID
                      join menu in await _menuRepository.GetAllAsync() on rm.MID equals menu.MenuId
                      where u.UserId == userId && ur.IsDeleted == false
                      select new
                      {
                          u.UserName,
                          menu.Url,
                          menu.MenuName,
                      };
            var dto = res.ToList().Select(x => new MenuDto
            {
                UserName = x.UserName,
                Url = x.Url,
                MenuName = x.MenuName,
            }).ToList();
            return dto;

        }
    }
}
